package com.springboot.wisdom.system.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.pagehelper.util.StringUtil;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.springboot.wisdom.common.common.ResultUtil;
import com.springboot.wisdom.common.common.bean.DeleteDTO;
import com.springboot.wisdom.common.common.bean.MyResult;
import com.springboot.wisdom.serviceApi.system.model.dto.MenuDTO;
import com.springboot.wisdom.serviceApi.system.model.entity.MenuDO;
import com.springboot.wisdom.serviceApi.system.model.vo.MenuTree;
import com.springboot.wisdom.system.mapeer.MenuMapper;
import com.springboot.wisdom.system.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class MenuServiceImpl extends MPJBaseServiceImpl<MenuMapper, MenuDO> implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    /**
     * 0：表示根顶级菜单。
     *
     * @return
     */
    @Override
    public MyResult<List<?>> getTree() {
        /**
         * SELECT a.menu_id, a.menu_name,a.parent_id,b.menu_id, b.menu_name,b.parent_id
         * FROM sys_menu a
         * left JOIN sys_menu b ON (b.parent_id = a.menu_id)
         * WHERE a.parent_id=0
         */
        String subTable1 = "b";
        List<MenuTree> menuTrees = menuMapper.selectJoinList(MenuTree.class, new MPJLambdaWrapper<MenuDO>()
                .selectAll(MenuDO.class)
                .selectCollection(MenuTree::getChildren, map -> {
                    map.all(MenuDO.class);
                    return map;
                })
                .leftJoin(MenuDO.class, subTable1, MenuDO::getParentId, MenuDO::getMenuId)
                .eq(MenuDO::getParentId, "0")
        );
        return ResultUtil.success(filtrationNullValue2(menuTrees));
    }

    @Override
    public MyResult<List<?>> list(MenuDTO menuDTO) {
        menuDTO.setParentId(null);
        return ResultUtil.success(ListForTree(menuDTO));
    }

    @Override
    @Transactional
    public MyResult<String> add(MenuDTO dto) {
        int result = 0;
        // 添加根菜单。
        if (StringUtils.isBlank(dto.getParentId())) {
            result = menuMapper.insert(new MenuDO(null, dto.getMenuName(), dto.getMenuPath(), dto.getMenuPermissions()
                    , dto.getMenuType(), dto.getMenuIcon(), null
                    , "0", dto.getRemark(), null, "创建人", DateTime.now(), null));
        } else {  // 添加子菜单 及按钮菜单。
            MenuDO subMenu = new MenuDO(null, dto.getMenuName(), dto.getMenuPath(), dto.getMenuPermissions()
                    , dto.getMenuType(), dto.getMenuIcon(), null
                    , dto.getParentId(), dto.getRemark(), null, "创建人", DateTime.now(), null);
            result = menuMapper.insert(subMenu);
        }
        System.out.println("result = " + result);
        return result != 0 ? ResultUtil.success("添加成功") : ResultUtil.error("添加失败");
    }

    @Override
    public MyResult<String> edit(MenuDTO dto) {
        MenuDO deptDO = new MenuDO();
        deptDO.setMenuId(dto.getMenuId());
        deptDO.setMenuName(dto.getMenuName());
        deptDO.setMenuPath(dto.getMenuPath());
        deptDO.setMenuPermissions(dto.getMenuPermissions());
        deptDO.setRemark(dto.getRemark());
        deptDO.setUpdateTime(DateTime.now());
        int result = menuMapper.updateById(deptDO);
        return result > 0 ? ResultUtil.success("编辑成功") : ResultUtil.error("编辑失败");
    }

    @Override
    public MyResult<String> delete(String id) {
        int result = menuMapper.deleteById(id);
        return result > 0 ? ResultUtil.success("删除成功") : ResultUtil.error("删除失败");
    }

    @Override
    public MyResult<String> deleteTree(String id) {
        MenuDTO menuDTO = new MenuDTO();
        menuDTO.setParentId(id);
        List<?> menuDOS = ListForTree(menuDTO);
        List<String> ids = new ArrayList<>();
        ids.add(id);
        menuDOS.forEach(item -> {
            MenuTree itemData = (MenuTree) item;
            if (itemData != null) {
                ids.add(itemData.getMenuId());
                if (itemData.getChildren() != null) {
                    for (MenuTree child : itemData.getChildren()) {
                        ids.add(child.getMenuId());
                    }
                }
            }
        });
        int result = menuMapper.deleteByIds(ids);

        System.out.println("=========================");
        ids.forEach(System.out::println);
        System.out.println("=========================");


        return result > 0 ? ResultUtil.success("删除成功") : ResultUtil.error("删除失败");
    }

    @Override
    public MyResult<String> deleteList(DeleteDTO<String> dto) {
        int result = menuMapper.deleteByIds(dto.getIdList());
        return result > 0 ? ResultUtil.success("删除成功 " + result + " 条") : ResultUtil.error("删除失败");
    }


    /**
     * 获取三层树形列表。
     *
     * @param menuDTO
     * @return
     */
    private List<?> ListForTree(MenuDTO menuDTO) {
        String subTable1 = "b";
        String subTable2 = "c";
        List<MenuTree> menuTrees = menuMapper.selectJoinList(MenuTree.class, new MPJLambdaWrapper<MenuDO>()
                .selectAll(MenuDO.class)
                .selectCollection(MenuTree::getChildren, map1 -> {
                    map1.all(subTable1, MenuDO.class);
                    map1.result(MenuDO::getMenuName);
                    map1.collection(MenuTree::getChildren, map2 -> {
                        map2.all(subTable2, MenuDO.class);
                        map1.result("t", MenuDO::getMenuName, MenuTree::getParentName);
                        map2.result(subTable1, MenuDO::getMenuName, MenuTree::getParentName);
                        return map2;
                    });
                    return map1;
                })
                .leftJoin(MenuDO.class, subTable1, MenuDO::getParentId, MenuDO::getMenuId)
                .leftJoin(MenuDO.class, subTable2, MenuDO::getParentId, subTable1, MenuDO::getMenuId)
                // 查询名称。
                .eqIfExists(subTable1, MenuDO::getMenuName, menuDTO.getMenuName())
                .eq(MenuDO::getParentId, StringUtil.isEmpty(menuDTO.getParentId()) ? "0" : menuDTO.getParentId())
        );

        return filtrationNullValue3(menuTrees);
    }

    /**
     * 过滤空值 2层。
     *
     * @param menuTrees
     * @return
     */
    public List<MenuTree> filtrationNullValue2(List<MenuTree> menuTrees) {
        for (MenuTree menuTree : menuTrees) {
            for (MenuTree child : menuTree.getChildren()) {
//                System.out.println("menuTree = " + menuTree);
//                System.out.println("child = " + child);
                if (child.getMenuId() == null) {
                    menuTree.setChildren(null);
                }
            }
        }
        return menuTrees;
    }

    /**
     * 过滤空值 3层。
     *
     * @param menuTrees
     * @return
     */
    public List<MenuTree> filtrationNullValue3(List<MenuTree> menuTrees) {
        for (MenuTree menuTree : menuTrees) {
            for (MenuTree child : menuTree.getChildren()) {
//                System.out.println("menuTree = " + menuTree);
//                System.out.println("child = " + child);
                if (child.getMenuId() == null) {
                    menuTree.setChildren(null);
                    continue;
                }
                for (MenuTree childChild : child.getChildren()) {
                    System.out.println("childChild = " + childChild);
                    if (childChild.getMenuId() == null) {
                        child.setChildren(null);
                    }
                }
            }
        }
        return menuTrees;
    }
}